package gamedata

import (
	"fmt"
	"io"
	"math/rand"
	"os"
	"sort"
	"strconv"
	"strings"
	"time"

	// "io/ioutil"
	"net/http"

	"server/pkg/github.com/name5566/leaf/recordfile"
)

type TestRecord struct {
	// index 0
	IndexInt int "index"
	// index 1
	IndexStr string "index"
	_Number  int32
	Str      string
	Arr1     [2]int
	Arr2     [3][2]int
	Arr3     []int
	St       struct {
		Name string "name"
		Num  int    "num"
	}
	M map[string]int
}

type MergeDataRecord struct {
	// index 0
	Id int "index"
	// index 1
	Lv      int
	MaxLv   int
	Icon    string
	Color   string
	Title   string
	Content string

	SellType     string
	SellNum      int
	Star         int
	Origin       string
	Capacity     int
	CoolTime     int
	CoolNum      int
	Emit_List    string
	SellDiamond  int
	Relative     string
	Type         string
	Emit_ID      string
	Emit_Type    string
	Product_Type string
	Order_Score  int
}

type ShopItemRecord struct {
	// index 0
	Id int "index"
	// index 1
	Group      string
	ObjId      string
	SellType   string
	SellPrice  float32
	TotalCount int
}

type ShopPackRecord struct {
	// index 0
	Id int "index"
	// index 1
	Title      string
	Content    string
	Price_Old  float32
	Price_New  float32
	Discount   float32
	TotalCount int
}

type ActivityRecord struct {
	// index 0
	Id int "index"
	// index 1
	ActivtyName    string
	ActiveCfgNames string
	Type           int
	StartTime      string
	Duration       int32
}

type LimiteEvent struct {
	// index 0
	Id int "index"
	// index 1
	EventName string
	Type      int
	StartTime string
	Duration  string
	AddTimes  string
}
type LevelUpPackRecord struct {
	// index 0
	Id int "index"
	// index 1
	Level       int "index"
	RewardIds   string
	RewardCnt   string
	Price       float32
	OriginPrice float32
	Describe    string
}

type GrowthFundRecord struct {
	// index 0
	Id int "index"
	// index 1
	Level       int "index"
	RewardIds   string
	RewardCnt   string
	Price       float32
	OriginPrice float32
	Describe    string
}

type CardDetailRecord struct {
	// index 0
	Id           int "index"
	PictureAlbum int
	Icon         string
	Color        int
	Star         int
	ImageRes     string
	IsGold       int
	Name         string
}

type RandomNameDataBase struct {
	// index 0
	Id     int "index"
	EnName string
	CnName string
	Gender int
}

type ChampshipScoreReward struct {
	// index 0
	Id         int "index"
	ScoreNeed  int
	ItemReward string
	SortId     int
}

var G_AllConfigs = map[string]interface{}{
	// "test": TestRecord{},
	"MergeData":            MergeDataRecord{},
	"ShopItem":             ShopItemRecord{},
	"ShopPack":             ShopPackRecord{},
	"Activity":             ActivityRecord{},
	"LevelUpBuyPack":       LevelUpPackRecord{},
	"GrowthFund":           GrowthFundRecord{},
	"LimiteEvent":          LimiteEvent{},
	"CardDetailCfg":        CardDetailRecord{},
	"RandomNameDataBase":   RandomNameDataBase{},
	"ChampshipScoreReward": ChampshipScoreReward{},
}

var G_AllConfigsData = map[string]*recordfile.RecordFile{}

func InitReadAllCfg() {
	// 遍历 Map
	for k, v := range G_AllConfigs {
		rd := readRfNew(v, k)
		G_AllConfigsData[k] = rd
	}
}

func GetConfigByName(name string) *recordfile.RecordFile {
	_, ok := G_AllConfigsData[name]
	if ok {
		return G_AllConfigsData[name]
	} else {
		rd := readRfNew(G_AllConfigs[name], name)
		G_AllConfigsData[name] = rd
	}
	return G_AllConfigsData[name]
}

func GetGoldCardCfgsByStar(star int) []*CardDetailRecord {
	CardDetailCfg := GetConfigByName("CardDetailCfg")
	cfgs := []*CardDetailRecord{}
	for i := 0; i < CardDetailCfg.NumRecord(); i++ {
		record := CardDetailCfg.Record(i).(*CardDetailRecord)
		if record.IsGold == 1 && record.Star == star {
			cfgs = append(cfgs, record)
		}

	}
	return cfgs
}

func DisorderLuaTable(length int, Cnt int) []int {

	// length := len(tb)
	rand.Seed(time.Now().Unix())
	indexList := []int{}
	contentList := []int{}
	copy := []int{}
	for i := 0; i < Cnt; i++ {
		index := rand.Intn(length - i)
		if len(indexList) == 0 {
			indexList = append(indexList, index)
		} else {
			for n := 0; n < len(copy); n++ {
				if index >= copy[n] {
					index = index + 1
				}
			}
			indexList = append(indexList, index)
		}
		copy = []int{}
		for j := 0; j < len(indexList); j++ {
			copy = append(copy, indexList[j])
		}

		sort.Slice(copy, func(i, j int) bool { return copy[i] < copy[j] })
	}
	contentList = indexList[:]
	return contentList
}
func GetRandomDifferenceSet(star int, Exclude string) (*CardDetailRecord, string) {
	Records := GetGoldCardCfgsByStar(star)
	ExInts := []int{}
	RetExInts := []*CardDetailRecord{}
	if Exclude != "" {
		units := strings.Split(Exclude, ";")
		for i := 0; i < len(units); i++ {
			id, _ := strconv.Atoi(units[i])
			ExInts = append(ExInts, id)
		}
	}
	index := 0
	if len(Records) == len(ExInts) {
		index = rand.Intn(len(Records))
		return Records[index], strconv.Itoa(Records[index].Id)
	}

	IsHaveFunc := func(id int) bool {
		for i := 0; i < len(ExInts); i++ {
			if ExInts[i] == id {
				return true
			}
		}
		return false
	}

	for i := 0; i < len(Records); i++ {
		if !IsHaveFunc(Records[i].Id) {
			RetExInts = append(RetExInts, Records[i])
		}
	}
	index = rand.Intn(len(RetExInts))
	if Exclude == "" {
		return RetExInts[index], strconv.Itoa(RetExInts[index].Id)
	}
	return RetExInts[index], Exclude + ";" + strconv.Itoa(RetExInts[index].Id)

}

func ReadConfigFromAllConfig(path string) {
	apiUrl := "http://127.0.0.1:8080/api/ReadConfig"
	// URL param
	data := fmt.Sprintf("static/%s", path)
	contentType := "application/json"

	resp, err := http.Post(apiUrl, contentType, strings.NewReader(data))
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	b, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(b))
	parseWriteConfig(path, string(b))
}

// 写入text文件内容
func parseWriteConfig(confPath, info string) ([]byte, error) {
	fl, err := os.OpenFile("gamedata/"+confPath, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		fmt.Println("打开文件失败")
	}
	defer fl.Close()
	byteinfo := []byte(info)
	n, err := fl.Write(byteinfo)
	if err == nil && n < len(byteinfo) {
		fmt.Println("写入失败")
		fmt.Println(err)
	}
	return byteinfo, err
}
